package ar.edu.itba.it.cg.grupo01.vehicle;

import java.util.Date;

import ar.edu.itba.it.cg.grupo01.game.GameEndingState;

import com.jme.input.InputHandler;
import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.renderer.Renderer;
import com.jme.scene.Node;
import com.jme.system.DisplaySystem;
import com.jmex.font2d.Font2D;
import com.jmex.font2d.Text2D;

public class Hud {
	final double topHeightPercent = 0.9;
	final double bottomPercent = 0.1;
	final double leftPercent = 0.05;
	final double rightPercent = 0.8;

	boolean playCountdown;

	DisplaySystem disp;
	Node parentNode;
	// stuff to display
	String speed;
	String points;
	String time;
	String currentLap;
	String totalLaps;
	String lastLapTime;
	String playerName;
	String hudScore;
	String highscore;
	String countdown;

	// screen text
	Text2D speedLabel;
	Text2D speedHud;

	Text2D timeLabel;
	Text2D timeHud;

	Text2D totalLapsLabel;
	Text2D totalLapsHud;

	Text2D pointsHud;
	Text2D pointsHudLabel;

	Text2D lastLapTimeHud;
	Text2D lastLapTimeHudLabel;

	Text2D highScoreHud;
	Text2D highScoreHudLabel;

	Text2D countdownHud;

	Text2D gameEndHud;

	private long startCountdown;
	private int countdownSecs;
	private InputHandler input;
	private boolean playGameEnd;
	private long startGameEnd;
	private GameEndingState gameEndType;
	private Text2D gameEndScoreHud;

	public boolean isGameEnd() {
		return playGameEnd;
	}

	public void setGameEnd(boolean gameEnd) {
		this.playGameEnd = gameEnd;
	}

	public GameEndingState getGameEndType() {
		return gameEndType;
	}

	public void setGameEndType(GameEndingState endState) {
		this.gameEndType = endState;
	}

	public Hud(Node hudNode, DisplaySystem disp) {
		this.parentNode = hudNode;
		this.disp = disp;
		time = "00";
		currentLap = "0";
		totalLaps = "0";
		points = "0";
		highscore = "--";
		countdownSecs = 3;
		startCountdown = 0;
		playCountdown = false;
		playGameEnd = false;
	}

	public String getPoints() {
		return points;
	}

	public void setPoints(String points) {
		this.points = points;
	}

	public void drawHud() {

		drawTime();

		drawLaps();

		drawSpeed();

		drawPoints();

		attachNodes();

		drawHighScore();

		if (playCountdown)
			drawCountdown();
		if (playGameEnd)
			drawGameEnd();

	}

	private void drawCountdown() {
		long time = new Date().getTime() - startCountdown;
		System.out.println("reset time: " + time);
		if (time >= 0 && time < countdownSecs * 1000) {
			countdownHud = new Font2D().createText(String.valueOf(countdownSecs
					- (time / 1000)), 20, 0);
		} else if (time > countdownSecs * 1000
				&& time < (countdownSecs + 1) * 1000) {
			countdownHud = new Font2D().createText("GO!!", 20, 0);
		} else {
			countdownHud = new Font2D().createText(String.valueOf("GO!!"), 20,
					0);
			playCountdown = false;
			this.input.setEnabled(true);
		}

		Vector3f pos = new Vector3f((float) (disp.getWidth() / 2),
				(float) (disp.getHeight() / 2), 0);
		countdownHud.setLocalTranslation(pos);
		countdownHud.setTextColor(ColorRGBA.red);
		countdownHud.setLocalScale(7.0f);
		countdownHud.updateRenderState();
		countdownHud.setRenderQueueMode(Renderer.QUEUE_ORTHO);
		countdownHud.draw(disp.getRenderer());
	}

	public int getCountdownSecs() {
		return countdownSecs;
	}

	public void setCountdownSecs(int countdownSecs) {
		this.countdownSecs = countdownSecs;
	}

	private void drawHighScore() {
		highScoreHud = new Font2D().createText(highscore, 20, 0);
		Vector3f pos = new Vector3f((float) (disp.getWidth() * leftPercent),
				(float) (disp.getHeight() * topHeightPercent), 0);
		highScoreHud.setLocalTranslation(pos);
		highScoreHud.setTextColor(ColorRGBA.red);
		highScoreHud.setLocalScale(2.0f);
		highScoreHud.updateRenderState();
		highScoreHud.draw(disp.getRenderer());

		highScoreHudLabel = new Font2D().createText("High score", 20, 0);
		highScoreHudLabel.setTextColor(ColorRGBA.yellow);
		highScoreHudLabel.setLocalTranslation(new com.jme.math.Vector3f(
				(float) (disp.getWidth() * leftPercent), (float) (disp
						.getHeight() - 15), 0));

	}

	public String getHighscore() {
		return highscore;
	}

	public void setHighscore(String highscore) {
		this.highscore = highscore;
	}

	private void drawPoints() {
		pointsHud = new Font2D().createText(points, 20, 0);
		Vector3f pos = new Vector3f((float) (disp.getWidth() * leftPercent),
				(float) (disp.getHeight() * bottomPercent), 0);
		pointsHud.setLocalTranslation(pos);
		pointsHud.setTextColor(ColorRGBA.red);
		pointsHud.setLocalScale(2.0f);
		pointsHud.updateRenderState();
		pointsHud.draw(disp.getRenderer());

		pointsHudLabel = new Font2D().createText("Score", 20, 0);
		pointsHudLabel.setTextColor(ColorRGBA.yellow);
		pointsHudLabel.setLocalTranslation(new com.jme.math.Vector3f(
				(float) (disp.getWidth() * leftPercent), (float) (disp
						.getHeight() * bottomPercent) + 35, 0));

	}

	public void updateHud() {

		parentNode.detachAllChildren();
		drawTime();
		drawLaps();
		drawSpeed();
		drawPoints();
		drawHighScore();
		if (playCountdown)
			drawCountdown();
		if (playGameEnd)
			drawGameEnd();

		attachNodes();

	}

	private void attachNodes() {
		parentNode.attachChild(timeHud);
		parentNode.attachChild(timeLabel);
		parentNode.attachChild(totalLapsHud);
		parentNode.attachChild(totalLapsLabel);
		parentNode.attachChild(speedHud);
		parentNode.attachChild(speedLabel);
		parentNode.attachChild(pointsHud);
		parentNode.attachChild(pointsHudLabel);
		parentNode.attachChild(highScoreHud);
		parentNode.attachChild(highScoreHudLabel);
		if (playCountdown)
			parentNode.attachChild(countdownHud);
		if (playGameEnd)
			parentNode.attachChild(gameEndHud);
		if (gameEndType == GameEndingState.WIN)
			parentNode.attachChild(gameEndScoreHud);
	}

	private void drawSpeed() {
		speedHud = new Font2D().createText(speed + "km/h", 20, 0);
		Vector3f pos = new Vector3f((float) (disp.getWidth() * rightPercent),
				(float) (disp.getHeight() * bottomPercent), 0);
		speedHud.setLocalTranslation(pos);
		speedHud.setTextColor(ColorRGBA.red);
		speedHud.setLocalScale(2.0f);
		speedHud.updateRenderState();
		speedHud.draw(disp.getRenderer());

		speedLabel = new Font2D().createText("Speed", 20, 0);
		speedLabel.setTextColor(ColorRGBA.yellow);
		speedLabel.setLocalTranslation(new com.jme.math.Vector3f((float) (disp
				.getWidth() * rightPercent), (float) (disp.getHeight()
				* bottomPercent + 35), 0));

	}

	public String getSpeed() {
		return speed;
	}

	public void setSpeed(String speed) {
		this.speed = speed;
	}

	public String getTime() {
		return time;
	}

	public void setTime(String time) {
		this.time = time;
	}

	public String getCurrentLap() {
		return currentLap;
	}

	public void setCurrentLap(String currentLap) {
		this.currentLap = currentLap;
	}

	public String getTotalLaps() {
		return totalLaps;
	}

	public void setTotalLaps(String totalLaps) {
		this.totalLaps = totalLaps;
	}

	public String getPlayerName() {
		return playerName;
	}

	public void setPlayerName(String playerName) {
		this.playerName = playerName;
	}

	private void drawLaps() {

		totalLapsHud = new Font2D().createText(currentLap + "/" + totalLaps,
				20, 0);
		Vector3f pos = new Vector3f((float) (disp.getWidth() * rightPercent),
				(float) (disp.getHeight() * topHeightPercent), 0);
		totalLapsHud.setLocalTranslation(pos);
		totalLapsHud.setTextColor(ColorRGBA.red);
		totalLapsHud.setLocalScale(2.0f);
		totalLapsHud.updateRenderState();
		totalLapsHud.draw(disp.getRenderer());

		totalLapsLabel = new Font2D().createText("Laps", 20, 0);
		totalLapsLabel.setLocalTranslation(new com.jme.math.Vector3f(
				(float) (disp.getWidth() * rightPercent), (float) (disp
						.getHeight() - 15), 0));
		totalLapsLabel.setTextColor(ColorRGBA.yellow);

	}

	private void drawTime() {

		timeLabel = new Font2D().createText("TIME", 20, 0);
		timeLabel.setLocalTranslation(new com.jme.math.Vector3f(
				disp.getWidth() / 2, disp.getHeight() - 15, 0));
		timeLabel.setTextColor(ColorRGBA.yellow);

		timeHud = new Font2D().createText(time, 20, 0);
		timeHud.setLocalTranslation(new com.jme.math.Vector3f(disp.getWidth()
				/ 2 - 4 * time.length(),
				(float) (disp.getHeight() * topHeightPercent), 0));
		timeHud.setTextColor(ColorRGBA.red);
		timeHud.setLocalScale(2.0f);

	}

	private void drawGameEnd() {
		
		if( gameEndType == GameEndingState.NOTOVER ) {
			return;
		}
		
		if (gameEndType != GameEndingState.WIN)
			gameEndHud = new Font2D().createText("GAME OVER", 20, 0);
		else {
			gameEndHud = new Font2D().createText("YOU WIN", 20, 0);
			gameEndScoreHud = new Font2D().createText("Your score is "
					+ this.points, 20, 0);
		}

		Vector3f pos = new Vector3f((float) (disp.getWidth() / 3 - 225),
				(float) (disp.getHeight() / 2), 0);
		gameEndHud.setLocalTranslation(pos);
		gameEndHud.setTextColor(ColorRGBA.red);
		gameEndHud.setLocalScale(7.0f);
		gameEndHud.updateRenderState();
		gameEndHud.setRenderQueueMode(Renderer.QUEUE_ORTHO);
		gameEndHud.draw(disp.getRenderer());

		if (gameEndType == GameEndingState.WIN) {
			Vector3f pos2 = new Vector3f((float) (disp.getWidth() / 4 - 60),
					(float) (disp.getHeight() / 2 - 100), 0);
			gameEndScoreHud.setLocalTranslation(pos2);
			gameEndScoreHud.setTextColor(ColorRGBA.red);
			gameEndScoreHud.setLocalScale(3.0f);
			gameEndScoreHud.updateRenderState();
			gameEndScoreHud.setRenderQueueMode(Renderer.QUEUE_ORTHO);
			gameEndScoreHud.draw(disp.getRenderer());
		}

	}

	public void playCountdown(InputHandler input) {
		playCountdown = true;
		startCountdown = new Date().getTime();
		this.input = input;
		this.input.setEnabled(false);
	}

	public void playGameEnd(InputHandler input) {
		playGameEnd = true;
		startGameEnd = new Date().getTime();
		this.input = input;
	}

	public boolean isPlayingCountdown() {
		return this.playCountdown;
	}

}
